<template>
    <div class="page-container">
      <div class="page">
        <div class="header">
          <h1><i class="fas fa-robot"></i> DeepSeek AI对话助手</h1>
          <p>基于DeepSeek AI模型的智能对话体验</p>
        </div>
        <div class="chat-container" ref="chatContainer">
          <div class="info-message" v-if="messages.length === 0">
            欢迎使用DeepSeek AI助手！我可以回答您关于Vue和其他技术问题。
          </div>
          <div v-for="(message, index) in messages" :key="index"
            :class="['message', message.role === 'user' ? 'user-message' : 'ai-message']">
            <div v-if="message.role === 'assistant'" class="avatar ai-avatar">
              <i class="fas fa-robot"></i>
            </div>
  
            <div class="message-wrapper">
              <div class="message-content">
                <div v-if="message.isTyping" class="typing-indicator">
                  <div class="typing-dot"></div>
                  <div class="typing-dot"></div>
                  <div class="typing-dot"></div>
                </div>
                <div v-else v-html="renderMarkdown(message.content)" class="markdown-body"></div>
              </div>
              <div class="message-time">{{ formatTime(message.timestamp) }}</div>
            </div>
  
            <div v-if="message.role === 'user'" class="avatar user-avatar">
              <i class="fas fa-user"></i>
            </div>
          </div>
  
          <div v-if="error" class="error-message">
            <i class="fas fa-exclamation-circle"></i> {{ error }}
          </div>
        </div>
        <div class="input-area">
          <input type="text" v-model="userInput" placeholder="输入您的问题..." @keyup.enter="sendMessage" :disabled="isLoading">
          <button @click="sendMessage" :disabled="isLoading || !userInput.trim()">
            <span v-if="!isLoading">发送</span>
            <span v-else>发送中...</span>
          </button>
        </div>
      </div>
    </div>
  </template>
  <script>
  import { marked } from 'marked'; // 引入marked库
  import DOMPurify from 'dompurify'; // 可选，但强烈推荐用于安全净化
  import axios from 'axios'
  export default {
    name: 'ChatApp',
    data() {
      return {
        messages: [],
        userInput: '',
        isLoading: false,
        error: null,
        chatContainer: null,
        apiBase: 'http://127.0.0.1:3000'
      };
    },
    mounted() {
      this.chatContainer = this.$refs.chatContainer;
      // 欢迎语
      this.addMessage(
        'assistant',
        '您好！我是 DeepSeek AI 助手，很高兴为您服务。请问有什么可以帮您的？',
        false
      );
      // 加载历史
      this.loadHistory();
    },
    methods: {
      /* 工具函数 */
      renderMarkdown(content) {
        const rawHtml = marked.parse(content);
        return DOMPurify.sanitize(rawHtml);
      },
      formatTime(timestamp, showSeconds = false) {
        console.log('timestamp----', timestamp);
        if (!timestamp) return '';
        const date = new Date(timestamp);
        const result = date.getFullYear() + '-' +
          String(date.getMonth() + 1).padStart(2, '0') + '-' +
          String(date.getDate()).padStart(2, '0') + ' ' +
          String(date.getHours()).padStart(2, '0') + ':' +
          String(date.getMinutes()).padStart(2, '0') + ':' +
          String(date.getSeconds()).padStart(2, '0');
  
        return result;
      },
  
      /* 发送消息 */
      async sendMessage() {
        if (!this.userInput.trim() || this.isLoading) return;
  
        const userMessage = this.userInput;
        this.userInput = '';
        this.error = null;
  
        // 记录用户发送消息的时间
        const userMessageTime = new Date();
        this.addMessage('user', userMessage, false, userMessageTime);
  
        this.addMessage('assistant', '', true);
        this.isLoading = true;
  
        try {
          const conversationHistory = this.messages
            .filter(m => !m.isTyping)
            .map(m => ({
              role: m.role === 'user' ? 'user' : 'assistant',
              content: m.content
            }));
  
          const res = await axios.post(`${this.apiBase}/get-chat`, {
            message: userMessage,
            conversationHistory
          });
  
          if (res.data.code === 0) {
            this.messages.pop(); // 移除"正在输入"的消息
  
            // 使用接口返回的服务器时间创建AI消息
            const serverTime = new Date(res.data.data.timestamp);
            this.addMessage('assistant', res.data.data.response, false, serverTime);
          } else {
            throw new Error(res.data.msg);
          }
        } catch (err) {
          console.error('API 请求错误:', err);
          this.messages.pop();
          this.error = '请求失败: ' + (err.response?.data?.msg || err.message);
  
          // 错误情况下，使用当前时间作为AI消息时间
          this.addMessage('assistant', '抱歉，请求出现错误，请稍后重试。', false, new Date());
        } finally {
          this.isLoading = false;
        }
      },
  
      /* 加载历史记录 */
      async loadHistory() {
        try {
          const res = await axios.get(`${this.apiBase}/get-history`);
          if (res.data.code === 0 && res.data.data.length) {
            res.data.data.reverse().forEach(item => {
              const t = new Date(item.created_at || item.timestamp);
              this.addMessage('user', item.user_message, false, t);
              this.addMessage('assistant', item.ai_response, false, t);
              // this.addMessage('user', item.user_message, false);
              // this.addMessage('assistant', item.ai_response, false);
            });
          }
        } catch (err) {
          console.error('加载历史记录失败:', err);
        }
      },
  
      // 修改 addMessage 方法，接受外部传入的时间戳
      addMessage(role, content, isTyping, externalTimestamp = null) {
        const timestamp = externalTimestamp ? new Date(externalTimestamp) : new Date();
        this.messages.push({
          role,
          content,
          isTyping,
          timestamp: timestamp // 使用传入的时间戳或当前时间
        });
        this.$nextTick(() => {
          if (this.chatContainer) {
            this.chatContainer.scrollTop = this.chatContainer.scrollHeight;
          }
        });
      }
    }
  };
  </script>
  <style scoped>
  .page-container {
    background: linear-gradient(135deg, #6e8efb, #a777e3);
    color: #333;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
  }
  
  .page {
    width: 100%;
    max-width: 900px;
    border-radius: 20px;
    box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 95vh;
    backdrop-filter: blur(5px);
    margin: 0 auto;
  }
  
  .header {
    background: linear-gradient(90deg, #4b6cb7 0%, #182848 100%);
    color: white;
    padding: 20px 30px;
    text-align: center;
    position: relative;
    overflow: hidden;
  }
  
  .header::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
    transform: rotate(30deg);
  }
  
  .header h1 {
    font-size: 28px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    font-weight: 600;
  }
  
  .header h1 i {
    margin-right: 12px;
    font-size: 32px;
  }
  
  .header p {
    font-size: 16px;
    opacity: 0.85;
    position: relative;
  }
  
  .chat-container {
    flex: 1;
    overflow-y: auto;
    padding: 25px;
    background: #f8f9fa;
    display: flex;
    flex-direction: column;
    position: relative;
  }
  
  .chat-container::-webkit-scrollbar {
    width: 8px;
  }
  
  .chat-container::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.05);
    border-radius: 10px;
  }
  
  .chat-container::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.2);
    border-radius: 10px;
  }
  
  .info-message {
    text-align: center;
    color: #7f8c8d;
    font-size: 15px;
    margin: 20px 0;
    padding: 15px;
    background: rgba(255, 255, 255, 0.7);
    border-radius: 12px;
    backdrop-filter: blur(5px);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
  }
  
  .message {
    margin-bottom: 25px;
    display: flex;
    animation: fadeIn 0.4s ease;
  }
  
  .user-message {
    justify-content: flex-end;
  }
  
  .ai-message {
    justify-content: flex-start;
  }
  
  .message-wrapper {
    max-width: 75%;
    display: flex;
    flex-direction: column;
  }
  
  .user-message .message-wrapper {
    align-items: flex-end;
  }
  
  .ai-message .message-wrapper {
    align-items: flex-start;
  }
  
  .message-content {
    padding: 16px 20px;
    border-radius: 20px;
    line-height: 1.5;
    position: relative;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.07);
    max-width: 100%;
  }
  
  .user-message .message-content {
    background: #EDF3FE;
    /* background: linear-gradient(135deg, #4b6cb7 0%, #3b5998 100%); */
    color: white;
    border-bottom-right-radius: 5px;
  }
  
  .ai-message .message-content {
    background: white;
    color: #2d3748;
    border: 1px solid #e9ecef;
    border-bottom-left-radius: 5px;
  }
  
  .message-time {
    font-size: 12px;
    color: #718096;
    margin-top: 6px;
    padding: 0 5px;
  }
  
  .avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 12px;
    flex-shrink: 0;
    align-self: flex-end;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  }
  
  .user-avatar {
    background: linear-gradient(135deg, #4b6cb7 0%, #3b5998 100%);
    color: white;
  }
  
  .ai-avatar {
    background: linear-gradient(135deg, #182848 0%, #1e3c72 100%);
    color: white;
  }
  
  .typing-indicator {
    display: inline-flex;
    align-items: center;
    color: #718096;
    padding: 10px 0;
  }
  
  .typing-dot {
    width: 8px;
    height: 8px;
    background: #718096;
    border-radius: 50%;
    margin: 0 3px;
    animation: typingAnimation 1.4s infinite ease-in-out;
  }
  
  .typing-dot:nth-child(1) {
    animation-delay: 0s;
  }
  
  .typing-dot:nth-child(2) {
    animation-delay: 0.2s;
  }
  
  .typing-dot:nth-child(3) {
    animation-delay: 0.4s;
  }
  
  .input-area {
    padding: 20px;
    background: white;
    border-top: 1px solid #e9ecef;
    display: flex;
    align-items: center;
  }
  
  .input-area input {
    flex: 1;
    padding: 16px 20px;
    border: 1px solid #e2e8f0;
    border-radius: 24px;
    outline: none;
    font-size: 16px;
    transition: all 0.3s;
    background: #f8f9fa;
  }
  
  .input-area input:focus {
    border-color: #4b6cb7;
    box-shadow: 0 0 0 3px rgba(75, 108, 183, 0.15);
    background: white;
  }
  
  .input-area button {
    margin-left: 12px;
    padding: 16px 24px;
    background: linear-gradient(135deg, #4b6cb7 0%, #3b5998 100%);
    color: white;
    border: none;
    border-radius: 24px;
    cursor: pointer;
    font-weight: 600;
    transition: all 0.3s;
    box-shadow: 0 4px 10px rgba(75, 108, 183, 0.25);
  }
  
  .input-area button:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 15px rgba(75, 108, 183, 0.35);
  }
  
  .input-area button:active {
    transform: translateY(0);
  }
  
  .input-area button:disabled {
    background: #cbd5e0;
    transform: none;
    box-shadow: none;
    cursor: not-allowed;
  }
  
  .error-message {
    color: #e53e3e;
    text-align: center;
    padding: 12px;
    background: #fed7d7;
    border-radius: 12px;
    margin: 15px 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .error-message i {
    margin-right: 8px;
  }
  
  .markdown-body {
    background: transparent !important;
    font-size: 15px;
    line-height: 1.6;
  }
  
  .markdown-body pre {
    background-color: #f7fafc !important;
    border-radius: 8px;
    padding: 14px;
    overflow-x: auto;
    margin: 10px 0;
    border: 1px solid #e2e8f0;
  }
  
  .markdown-body code {
    background-color: rgba(237, 242, 247, 0.6);
    border-radius: 4px;
    padding: 0.2em 0.4em;
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    font-size: 14px;
  }
  
  .markdown-body pre code {
    background: none;
    padding: 0;
  }
  
  @keyframes fadeIn {
    from {
      opacity: 0;
      transform: translateY(15px);
    }
  
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
  
  @keyframes typingAnimation {
  
    0%,
    60%,
    100% {
      transform: translateY(0);
    }
  
    30% {
      transform: translateY(-5px);
    }
  }
  
  @media (max-width: 768px) {
    .page {
      height: 100vh;
      border-radius: 0;
    }
  
    body {
      padding: 0;
    }
  
    .message-wrapper {
      max-width: 85%;
    }
  
    .header h1 {
      font-size: 22px;
    }
  
    .header p {
      font-size: 14px;
    }
  
    .chat-container {
      padding: 15px;
    }
  
    .avatar {
      width: 36px;
      height: 36px;
      margin: 0 8px;
    }
  
    .input-area {
      padding: 15px;
    }
  
    .input-area input {
      padding: 14px;
    }
  
    .input-area button {
      padding: 14px 18px;
    }
  }
  </style>